/*
 * 使用示例:
 * const jwt = require('jwt/index')(options);
 * 1、app.use(jwt.verify); 中间件使用
 * 2、router.get('/jwt-router',jwt.verify,controller); 路由使用
 * 
 * options支持的参数:
 * 1、key token在header中的变量名
 * 2、state 解密后对象在ctx.state中保存的变量名
 * 3、jwt jwt加密配置
 *    jwt.secret 加密串，默认值:'middlewares-jwt'
 *    jwt.expireIn 有效时长，默认值:'30m'
 * 4、refresh refresh加密配置
 *    refresh.secret 加密串，默认值:'middlewares-refresh'
 *    refresh.expireIn 有效时长，默认值:'7d'
 */
'use strict';

const jwt = require('jsonwebtoken');

exports = module.exports = (options) => {
  options = options || {};
  options.key = options.key || 'jwt';
  options.state = options.state || 'user';
  options.jwt = options.jwt || Object.create({});
  options.jwt.secret = options.jwt.secret || 'middlewares-jwt';
  options.jwt.expireIn = options.jwt.expireIn || '30m';
  options.refresh = options.refresh || Object.create({});
  options.refresh.secret = options.refresh.secret || 'middlewares-refresh';
  options.refresh.expireIn = options.refresh.expireIn || '7d';
  return {
    sign: (obj) => {
      return {
        jwt: jwt.sign(obj, options.jwt.secret, { expiresIn: options.jwt.expireIn }),
        refresh: jwt.sign(obj, options.refresh.secret, { expiresIn: options.refresh.expireIn })
      };
    },
    verify: async(ctx, next) => {
      let token = ctx.header[options.key];
      if (!token) {
        ctx.throw(401);
        return;
      }
      let decoded;
      try {
        decoded = jwt.verify(token, options.jwt.secret);
      } catch (err) {
        ctx.throw(401);
        return;
      }
      ctx.state[options.state] = decoded;
      await next();
    },
    refresh: (token) => {
      try {
        var decoded = jwt.verify(token, options.refresh.secret);
        return {
          jwt: jwt.sign(decoded, options.jwt.secret, { expiresIn: options.jwt.expireIn }),
          refresh: jwt.sign(decoded, options.refresh.secret, { expiresIn: options.refresh.expireIn })
        };
      } catch (err) {
        return false;
      }
    }
  }
};